package labox.innovation.gameserver.templates.item;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javolution.util.FastList;

import labox.innovation.config.Config;
import labox.innovation.gameserver.model.L2ItemInstance;
import labox.innovation.gameserver.model.L2ItemInstance.ItemGradeType;
import labox.innovation.gameserver.model.actor.instance.FuzePcInstance;
import labox.innovation.gameserver.network.SystemMessageId;
import labox.innovation.gameserver.network.serverpackets.SystemMessage;
import labox.innovation.gameserver.skills.Stats;
import labox.innovation.gameserver.templates.item.FuzeEconomicManager.OPSTATE;
import labox.innovation.gameserver.templates.item.ItemBouns.ItemBounsType;
import labox.innovation.gameserver.templates.item.ItemCompositeConfig.ItemCompositeData;
import labox.innovation.gameserver.templates.item.ItemIdentifyConfig.ItemNums;
import labox.innovation.util.Rnd;

/**
 * ��Ʒ�ϳ�ϵͳ
 * 
 * @author zjj
 * 
 */
public class ItemCompositeManager {

	static Logger _log = LoggerFactory.getLogger(ItemCompositeManager.class.getName());

	private static final int MAX_RAND_CHANCE = 10000;

	public static final ItemCompositeManager getInstance() {
		return SingletonHolder._instance;
	}

	/**
	 * �ܷ�ϳ�
	 * 
	 * @param pc
	 * @param mainitemid
	 * @param itemids
	 * @return
	 */
	public boolean canComposite(FuzePcInstance pc, long mainitemid, long[] itemids) {
		if (pc == null) {
			return false;
		}
		L2ItemInstance mainitem = pc.getInventory().getItemByObjectId(mainitemid);
		if (mainitem == null) // ��װ��������
		{
			return false;
		}

		L2ItemInstance[] items = null;
		if (itemids != null && itemids.length > 0) {
			items = new L2ItemInstance[itemids.length];
			int i = 0;
			for (long id : itemids) {
				items[i] = pc.getInventory().getItemByObjectId(id);
				if (items[i] == null) // ����װ��������
				{
					return false;

				} else if (!items[i].getItem().getCanComposite()) {
					// TODO:
					// ����װ�� ������
					return false;
				}
				i++;
			}
		}

		ItemCompositeData compdata = ItemCompositeConfig.getInstance().getItemCompositeData(mainitem.getItemGrade(), mainitem.getItemLvl());
		// �жϸ���װ�� �Ƿ���Ҫ��
		if (compdata != null) {

			if (items != null && items.length < compdata._needitemnum) { // ��Ʒ��������
				pc.sendPacket(new SystemMessage(SystemMessageId.ITEM_FORGE_NUMS));
				return false;
			} else if (items == null && compdata._needitemnum > 0) {
				pc.sendPacket(new SystemMessage(SystemMessageId.ITEM_FORGE_NUMS));
				return false;
			}

			if (items != null) {

				for (L2ItemInstance temp : items) {
					if (temp.getItemGrade() != compdata._mustitemgrade) { // ����װ��
																			// Ʒ�ʲ����Ҫ��
						pc.sendPacket(new SystemMessage(SystemMessageId.ITEM_FORGE_ITEM_UNCOND));
						return false;
					}

					int lvlsub = temp.getItemLvl() - mainitem.getItemLvl();
					if (!(lvlsub >= compdata._downlvl && lvlsub <= compdata._uplvl)) { // װ���ȼ���䲻��
						pc.sendPacket(new SystemMessage(SystemMessageId.ITEM_FORGE_ITEM_UNCOND));
						return false;
					}

				}// end for( L2ItemInstance temp:items )

			}

		}// end ifif( compdata != null )
		else { // ʧ�ܣ� �������������
			_log.warn("װ���ϳ������ļ�������", Config.SERVER_ID);
			return false;
		}

		// �ж���ұ����� �Ƿ���ڱ���ĵ���
		for (ItemNums tn : compdata._consumeitems) {
			L2ItemInstance item = pc.getInventory().getItemByItemId(tn.itemId);
			if (item == null || item.getCount() < tn.itemNums) { // ��Ʒ������ ����
																	// ��Ʒ����������
																	// ��ôʧ�� ���ܺϳ�
				SystemMessage sm = new SystemMessage(SystemMessageId.ITEM_FORGE_UNCOND_S1);
				sm.addItemName(tn.itemId);
				pc.sendPacket(sm);
				return false;
			}
		}

		// ��Ҫ�� ������
		if (!pc.getInventory().hasEnoughSilverMoney(OPSTATE.FORGE.getValue(), pc, compdata._moneySilverNums)) {
			pc.sendPacket(new SystemMessage(SystemMessageId.YOU_NOT_ENOUGH_ADENA));
			return false;
		}

		return true;
	}

	/**
	 * �ϳ���Ʒ
	 * 
	 * @param mainitemid
	 *            : ����Ʒ
	 * @param itemids
	 *            : ������Ʒ
	 * @return
	 */
	public L2ItemInstance compositeItem(FuzePcInstance pc, long mainitemid, long[] itemids) {
		if (pc == null) {
			return null;
		}
		L2ItemInstance mainitem = pc.getInventory().getItemByObjectId(mainitemid);
		if (mainitem == null) // ��װ��������
		{
			return null;
		}

		L2ItemInstance[] items = null;
		if (itemids != null && itemids.length > 0) {
			items = new L2ItemInstance[itemids.length];
			int i = 0;
			for (long id : itemids) {
				items[i] = pc.getInventory().getItemByObjectId(id);
				i++;
			}
		}

		ItemCompositeData compdata = ItemCompositeConfig.getInstance().getItemCompositeData(mainitem.getItemGrade(), mainitem.getItemLvl());

		if (items != null) {

			// ���еļ��ͨ�� ��ô��ʼ�۳����
			for (L2ItemInstance iit : items) { // �۳���װ��
				pc.destroyItem("�ϳ������Ʒ", iit, 1, pc, true);
			}

		}

		for (ItemNums tn : compdata._consumeitems) { // �۳������ĵĵ���
			pc.destroyItemByItemId("�ϳ������Ʒ", tn.itemId, tn.itemNums, pc, true);
		}

		if (compdata._moneyType == FuzeEconomicManager.MONEY_TYPE_SILVER) {
			// �۳��ɫ���ϵ�������
			pc.reduceMoneySilver(OPSTATE.FORGE.getValue(), compdata._moneySilverNums, null, true);
		} else if (compdata._moneyType == FuzeEconomicManager.MONEY_TYPE_NOTE) {
			pc.reduceMoneyNote("�ϳ����", compdata._moneySilverNums, null, true);
		} else if (compdata._moneyType == FuzeEconomicManager.MONEY_TYPE_YUANBAO) {
			pc.reduceMoneyYuanBao("�ϳ����", compdata._moneySilverNums, null, true);
		}

		int chance = Rnd.get(MAX_RAND_CHANCE + 1);

		if (chance <= compdata._chance) {

			_log.info("������Ʒ: ��ɫ:" + pc.getName() + "(" + pc.getObjectId() + ")" + "����Ʒ:" + mainitem.getName() + "(" + mainitem.getObjectId() + ")" + "�ϳ�", pc.getObjectId(), pc.getName());
			// �ϳɳɹ�
			return compositeSuccess(mainitem, items, compdata._nextgrade);
		}

		// ����ʧ��Э��

		return null;

	}// end compositeItem

	/**
	 * �ϳɳɹ��� ��Ʒ������������
	 * 
	 * @param mainitem
	 * @param items
	 * @param newgrade
	 *            ���µ�Ʒ�ʵȼ�
	 * @return
	 */
	protected L2ItemInstance compositeSuccess(L2ItemInstance mainitem, L2ItemInstance[] items, int newgrade) {
		mainitem.setItemGrade(newgrade); // �����µ�Ʒ�ʵȼ�
		ItemGradeType gradetp = mainitem.getItemGradeType();
		ItemRandAttribute itemb = (ItemRandAttribute) mainitem.getItemBouns(ItemBounsType.RAND_ATTRIBUTES.ordinal());
		// ���и���װ���ϵ� ��������
		List<Stats> allstat = new FastList<Stats>();

		if (items != null) {
			// ��ø���װ���ϵ� ���и�������
			for (L2ItemInstance tt : items) {
				ItemRandAttribute itRab = (ItemRandAttribute) (tt.getItemBouns(ItemBounsType.RAND_ATTRIBUTES.ordinal()));
				if (itRab != null) {
					allstat.addAll(itRab.getRandStats());
				}
			}
		}

		int existNums = 0;
		// ��Ʒ �������� ��û��
		// ���һ����������
		if (itemb == null) {
			itemb = new ItemRandAttribute();
		} else {
			existNums = itemb.getAttriNums();
		}

		int gradenum = gradetp.getRandAttiNum() - existNums;
		int size = allstat.size();
		// System.out.println("�������Ը���:" + gradenum );
		while (gradenum > 0) // �����еĸ���װ���ĸ��������� ���һ����������
		{
			if (size <= 0)
				break;
			int index = Rnd.get(size);
			// �������� ��ɳɹ�
			// System.out.println("���Ӹ������� :" + allstat.get(index) );
			if (itemb.addItemAttri(allstat.get(index), newgrade, mainitem.getItemLvl(), mainitem.getItemWeight())) {
				gradenum--;
			}
			allstat.remove(index);
			size = allstat.size();

		}// end while( gradenum > 0 )

		// ���gradenum��Ϊ0 �� ��ô�����ָ�������� ��������
		// �����ں��������жϣ� ��������û�����ж�
		// System.out.println("ʣ�฽�����Ը���:" + gradenum );
		itemb.addItemAttri(gradenum, mainitem.getItemLvl(), mainitem.getItemWeight());

		// System.out.println("װ���ϵĸ������Ը���:" + itemb.getAttriNums() );
		mainitem.addItemBouns(itemb);
		// ����װ���;ö�
		mainitem.reduceEndurance((int) (mainitem.getEnduranceUp() * L2ItemInstance.REDUCEENRU_NUMS));

		return mainitem;
	}

	@SuppressWarnings("synthetic-access")
	private static class SingletonHolder {
		protected static final ItemCompositeManager _instance = new ItemCompositeManager();
	}

	private ItemCompositeManager() {
	}

}
